package net.wanho.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import net.wanho.dto.UserInfoDTO;
import net.wanho.dto.UserPwdDTO;
import net.wanho.mapper.AuthInfoMapper;
import net.wanho.po.AuthInfo;
import net.wanho.po.UserInfo;
import net.wanho.service.FileService;
import net.wanho.service.UserInfoService;
import net.wanho.mapper.UserInfoMapper;
import net.wanho.util.CurrentUtil;
import net.wanho.vo.PageInfo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【user_info(用户表)】的数据库操作Service实现
* @createDate 2025-01-10 17:10:35
*/
@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
    implements UserInfoService{

    private final RedisTemplate<String, Object> redisTemplate;
    private final AuthInfoMapper authInfoMapper;
    private final FileService fileService;

    @Override
    public PageInfo<UserInfo> listPage(int pageNum, int pageSize, UserInfoDTO userInfoDTO) {
        Page<UserInfo> page = new Page<>(pageNum, pageSize);

        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.like(!ObjectUtils.isEmpty(userInfoDTO.getUserCode()), "i.user_code", userInfoDTO.getUserCode());
        wrapper.eq(!ObjectUtils.isEmpty(userInfoDTO.getRoleId()), "r.role_id", userInfoDTO.getRoleId());
        wrapper.eq(!ObjectUtils.isEmpty(userInfoDTO.getUserState()), "i.user_state", userInfoDTO.getUserState());
        // 自定义Wraper时，不会自动添加逻辑删除条件isDelete
        wrapper.eq("i.is_delete", 0);
        wrapper.orderByAsc("i.user_id");

         this.baseMapper.selectByPage(page,wrapper);

        /**
         * 封装分页结果
         */
        PageInfo<UserInfo> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page.getCurrent());
        pageInfo.setPageSize(page.getSize());
        pageInfo.setTotalNum(page.getTotal());
        pageInfo.setPageCount(page.getPages());
        pageInfo.setLimitIndex(page.offset());
        pageInfo.setResultList(page.getRecords());

        /**
         * 获取创建人
         */
        // pageInfo.getResult().forEach(userInfo -> {
        //     userInfo.setGetCode(this.getById(userInfo.getCreateBy()).getUserCode());
        // });

        return pageInfo;
    }

    @Override
    public List<AuthInfo> findMenu() {
        /**
         * 读取Redis
         */
        List<AuthInfo> menus = (List<AuthInfo>) redisTemplate.opsForValue().get("user:menus:" + CurrentUtil.getId());
        if (! CollectionUtils.isEmpty(menus)){
            return menus;
        }

        /**
         * 获取当前用户的权限
         */
        List<AuthInfo> authInfoList = authInfoMapper.selectByUserId(CurrentUtil.getId());

        // 获取一级菜单
        menus = Optional.ofNullable(authInfoList).orElse(new ArrayList<>()).stream()
                .filter(item -> item.getParentId() == 0)
                .map(item -> {
                    // 递归查询子菜单
                    findChildren(item, authInfoList);
                    return item;
                })
                .collect(Collectors.toList());

        // 存入redis
        redisTemplate.opsForValue().set("user:menus:" + CurrentUtil.getId(), menus, 60 * 60 * 24, TimeUnit.SECONDS);

        return menus;
    }

    /**
     * 修改密码
     * @param userPwdDTO
     */
    @Override
    public void modifyPwd(UserPwdDTO userPwdDTO) {
        /**
         * 校验原密码
         */
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getUserId,  userPwdDTO.getId());
        wrapper.eq(UserInfo::getUserPwd, SecureUtil.md5(userPwdDTO.getOldPassword()));
        UserInfo userInfo = this.getOne(wrapper);
        if (ObjectUtils.isEmpty(userInfo)){
            throw new RuntimeException("原密码不正确！");
        }

        /**
         * 修改密码
         */
        userInfo = new UserInfo();
        userInfo.setUserId(userPwdDTO.getId());
        userInfo.setUserPwd(SecureUtil.md5(userPwdDTO.getPassword()));
        this.updateById(userInfo);
    }

    @Override
    public String modifyAvatar(Integer id, MultipartFile file) {
        // 上传文件
        String url = fileService.upload(file);

        // 修改用户头像
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(id);
        userInfo.setAvatar(url);
        this.updateById(userInfo);

        return url;
    }

    /**
     * 递归查询子菜单
     * @param item
     * @param authInfoList
     */
    private void findChildren(AuthInfo item, List<AuthInfo> authInfoList) {
        List<AuthInfo> children = authInfoList.stream()
                .filter(subItem -> subItem.getParentId().equals(item.getAuthId()))
                .map(subItem -> {
                    findChildren(subItem, authInfoList);
                    return subItem;
                })
                .collect(Collectors.toList());
        item.setChildAuth(children);
    }
}




